#ifndef _STDIO_H_
#define _STDIO_H_

#include <CType.h>

typedef enum {
    FAT12_TYPE,
    FAT16_TYPE,
    FAT32_TYPE
} FatType;

typedef struct {
    int8_t DrvNum;
    int16_t HeadCnt;
    int16_t SecInTrack;
    int32_t SecCount;
    int16_t BytePerSec;
    int8_t SecPerCluster;
    int32_t HiddenSecCnt;
    int32_t RootDirSecNum;
    int32_t FatSecNum;
    int32_t DataSecNum;
    int16_t FatSize;
    int16_t RootDirCnt;
    int8_t FatCount;
    FatType Ftype;
    int32_t ClusterEnd;
} DiskInfo;

typedef struct {
    int8_t Name[11];
    int8_t AttFlag;
    int16_t ModifyTime;
    int16_t ModifyDate;
    int32_t FirstCluster;
    int32_t Length;
    DiskInfo * di;
} FileInfo;

#define SIZE_OF_NT_SIGNATURE 4

typedef struct {
    int16_t e_magic;
    int16_t e_cblp;
    int16_t e_cp;
    int16_t e_crlc;
    int16_t e_cparhdr;
    int16_t e_minalloc;
    int16_t e_maxalloc;
    int16_t e_ss;
    int16_t e_sp;
    int16_t e_csum;
    int16_t e_ip;
    int16_t e_cs;
    int16_t e_lfarlc;
    int16_t e_ovno;
    int16_t e_res[4];
    int16_t e_oemid;
    int16_t e_oeminfo;
    int16_t e_res2[10];
    int32_t e_lfanew;
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;

typedef struct {
    int16_t Machine;
    int16_t NumberOfSections;
    int32_t TimeDateStamp;
    int32_t PointerToSymbolTable;
    int32_t NumberOfSymbols;
    int16_t SizeOfOptionalHeader;
    int16_t Characteristics;
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;

#define IMAGE_SIZEOF_FILE_HEADER                20

typedef struct {
    int32_t VirtualAddress;
    int32_t Size;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;

#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES        16

typedef struct {
    int16_t Magic;
    int8_t MajorLinkerVersion;
    int8_t MinorLinkerVersion;
    int32_t SizeOfCode;
    int32_t SizeOfInitializedData;
    int32_t SizeOfUninitializedData;
    int32_t AddressOfEntryPoint;
    int32_t BaseOfCode;
    int32_t BaseOfData;

    int32_t ImageBase;
    int32_t SectionAlignment;
    int32_t FileAlignment;
    int16_t MajorOperatingSystemVersion;
    int16_t MinorOperatingSystemVersion;
    int16_t MajorImageVersion;
    int16_t MinorImageVersion;
    int16_t MajorSubsystemVersion;
    int16_t MinorSubsystemVersion;
    int32_t Reserved1;
    int32_t SizeOfImage;
    int32_t SizeOfHeaders;
    int32_t CheckSum;
    int16_t Subsystem;
    int16_t DllCharacteristics;
    int32_t SizeOfStackReserve;
    int32_t SizeOfStackCommit;
    int32_t SizeOfHeapReserve;
    int32_t SizeOfHeapCommit;
    int32_t LoaderFlags;
    int32_t NumberOfRvaAndSizes;
    IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER;

#define IMAGE_SIZEOF_SHORT_NAME                 8

typedef struct {
    int8_t Name[IMAGE_SIZEOF_SHORT_NAME];
    union {
        int32_t PhysicalAddress;
        int32_t VirtualSize;
    } Misc;
    int32_t VirtualAddress;
    int32_t SizeOfRawData;
    int32_t PointerToRawData;
    int32_t PointerToRelocations;
    int32_t PointerToLinenumbers;
    int16_t NumberOfRelocations;
    int16_t NumberOfLinenumbers;
    int32_t Characteristics;
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;

#define IMAGE_DOS_SIGNATURE                     0x5A4D

#define EXPORT_BASE                             0x00020000

#define EXPORT_LIMIT                            0x000A0000

int16_t printf(int8_t * fmt, ...);

DiskInfo * loadDrvInfo(int8_t DrvNum);

FileInfo * parseFileInfo(int8_t * rawData);

FileInfo * searchFile(int8_t * filename, DiskInfo * di);

int16_t readFile(void * bfr, FileInfo * fi, int32_t offset, size_t size);

void * loadSec(int16_t secNum, DiskInfo * dsi);

void * loadSec0(int8_t DrvNum);

int16_t loadPE(int8_t * peName, DiskInfo * di);

void readBfr8(void * pv, void * bfr, size_t offset);

void readBfr16(void * pv, void * bfr, size_t offset);

void readBfr32(void * pv, void * bfr, size_t offset);

void DispAllFile(DiskInfo * di);

#define BPB_SEC_PER_TRACK_OFFSET    24

#define BPB_HEAD_CNT_OFFSET         26

#define BPB_TOTAL_SET16_OFFSET      19

#define BPB_TOTAL_SET32_OFFSET      32

#define BPB_FAT_SIZE_OFFSET         22

#define BPB_FAT_COUNT_OFFSET        16

#define BPB_ROOT_DIR_CNT_OFFSET     17

#define BPB_HIDDEN_SEC_OFFSET       28

#define BPB_BYTE_PER_SEC_OFFSET     11

#define BPB_SEC_PER_CLUSTER_OFFSET  13

#define FAT_FDT_SIZE                32

#endif _STDIO_H_ /* end of _STDIO_H_ */

